package com.gzist.security4.web.manage;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gzist.security4.domain.Permission;
import com.gzist.security4.mapper.PermissionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 自定义动态授权管理器
 * 旧版本使用
 *
 * @author: 黄泽建
 */
@Component
@Slf4j
public class SttAccessDecisionManager implements AccessDecisionManager {

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        if (o instanceof FilterInvocation) {
            FilterInvocation filterInvocation = (FilterInvocation) o;
            String uri = filterInvocation.getRequestUrl(); // 获取请求的URL路径
            // 原有的授权逻辑...
            log.info("访问路径=====》{}", uri);
            // 对于登录注册退出这些访问公共权限一致放行
            if (uri.equals("/user/login")||uri.equals("/error")) {
                log.info("登录成功=====》{}",uri);
                return;
            }
            // 根据当前访问路径去查询相应权限
            Permission permission = permissionMapper.selectOne(new QueryWrapper<Permission>().like("path", uri.replaceFirst("/", "")));
            log.info("路径权限=====》{}", permission);
            if (permission == null) {
                //当没找到对应权限的时候，说明资源上的权限发生了相应的更改，需要拦截下来进行告知说明，至于该如何做后面具体再考虑
                throw new IllegalArgumentException("没有权限哈哈哈！");
            }
            String perms = permission.getPerms();
            if (perms == null || perms.trim().equals("")) {
                // 当前访问路径存在而权限标识为空这一般是对于那些公共的按钮组件，均给放行
                return;
            }
            // 根据当前访问资源的权限来判断存否与当前用户的所有权限中
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                String s = authority.getAuthority();
                if (s.equals(perms)) {
                    // 循环遍历如果相等则说明有这权限
                    log.info("有权限，可以哦通过");
                    return;
                }
            }
            // 最后但上面情况都没有发生，便剩下最后一种情况就是当前用户没有访问当前接口的权限
            log.info("没有权限，可以哦通过");
            throw new IllegalArgumentException("没有权限哈哈哈！");
        }

    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true; // 默认支持所有类型的ConfigAttribute
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz); // 本例中仅支持FilterInvocation
    }
}
